
# pip install gitpython tqdm
import os
import git
import logging
import shutil
from getpass import getpass
from urllib.parse import urlparse
from tqdm import tqdm

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def get_repo_name_from_url(url):
    """从Git URL提取仓库名（去掉.git后缀）"""
    parsed = urlparse(url)
    repo_name = os.path.basename(parsed.path).replace('.git', '')
    return repo_name

def sync_git_repos(source_urls, target_url, local_base_dir, username=None, password=None):
    """
    同步多个源Git仓库到目标Git仓库的子目录
    Args:
        source_urls: 源仓库URL列表
        target_url: 目标仓库URL
        local_base_dir: 本地临时目录
        username: 目标仓库用户名（可选）
        password: 目标仓库密码（可选）
    """
    try:
        # 确保本地基目录存在
        if not os.path.exists(local_base_dir):
            os.makedirs(local_base_dir)
            logger.info(f"创建本地基目录: {local_base_dir}")

        # 克隆或更新目标仓库
        target_repo_dir = os.path.join(local_base_dir, "target_repo")
        if os.path.exists(target_repo_dir):
            logger.info(f"更新目标仓库: {target_url}")
            target_repo = git.Repo(target_repo_dir)
            target_repo.remotes.origin.pull()
        else:
            logger.info(f"克隆目标仓库: {target_url}")
            # 如果需要认证，构造带认证的URL
            if username and password:
                protocol, rest = target_url.split('://', 1)
                auth_url = f"{protocol}://{username}:{password}@{rest}"
            else:
                auth_url = target_url
            target_repo = git.Repo.clone_from(auth_url, target_repo_dir)

        # 使用进度条遍历每个源仓库
        for source_url in tqdm(source_urls, desc="同步源仓库", unit="repo"):
            repo_name = get_repo_name_from_url(source_url)
            source_repo_dir = os.path.join(local_base_dir, f"source_{repo_name}")

            # 克隆或更新源仓库
            if os.path.exists(source_repo_dir):
                logger.info(f"更新源仓库: {source_url}")
                source_repo = git.Repo(source_repo_dir)
                source_repo.remotes.origin.pull()
            else:
                logger.info(f"克隆源仓库: {source_url}")
                source_repo = git.Repo.clone_from(source_url, source_repo_dir)

            # 目标子目录路径
            target_sub_dir = os.path.join(target_repo_dir, repo_name)
            os.makedirs(target_sub_dir, exist_ok=True)

            # 复制源仓库内容到目标子目录（排除.git目录）
            logger.info(f"复制 {repo_name} 内容到目标仓库子目录: {target_sub_dir}")
            for item in os.listdir(source_repo_dir):
                if item != '.git':
                    src_path = os.path.join(source_repo_dir, item)
                    dst_path = os.path.join(target_sub_dir, item)
                    if os.path.isdir(src_path):
                        shutil.copytree(src_path, dst_path, dirs_exist_ok=True)
                    else:
                        shutil.copy2(src_path, dst_path)

            # 提交更改到目标仓库
            logger.info(f"提交 {repo_name} 的更改到目标仓库")
            # Use relative path from repo root for git add
            rel_path = os.path.relpath(target_sub_dir, start=target_repo_dir)
            target_repo.git.add(rel_path)
            if target_repo.is_dirty():
                target_repo.git.commit(m=f"Sync {repo_name} to {rel_path}")
            else:
                logger.info(f"{repo_name} 无更改，无需提交")

        # 推送目标仓库更改
        logger.info("推送所有更改到目标仓库...")
        target_repo.remotes.origin.push()

        logger.info("所有仓库同步完成！")

    except git.exc.GitCommandError as e:
        logger.error(f"Git操作失败: {e}")
        raise
    except Exception as e:
        logger.error(f"发生错误: {e}")
        raise

if __name__ == "__main__":
    # 源仓库列表
    SOURCE_URLS = [
        "https://gitee.com/kzeng/msprint_python_sdk.git",
        "https://gitee.com/kzeng/rfid_python_sdk.git",
        "https://gitee.com/kzeng/uhf_rfid_python_sdk.git",
        "https://gitee.com/kzeng/donsee_idreader_python_sdk.git",
        "https://gitee.com/kzeng/boku_sip2_api.git",
        "https://gitee.com/kzeng/boku_lift_api.git",
        "https://gitee.com/kzeng/bk-robot"
    ]
    TARGET_URL = "http://dev.bookgo.com.cn:2000/bg/rfid_hardware_api.git"
    LOCAL_BASE_DIR = "./sync_repos"

    # 获取目标仓库的认证信息
    username = input("请输入目标仓库用户名（留空则无认证）: ")
    password = getpass("请输入目标仓库密码（留空则无认证）: ") if username else None

    # 执行同步
    sync_git_repos(SOURCE_URLS, TARGET_URL, LOCAL_BASE_DIR, username, password)
